package com.flow.framework.base.system.checker.impl;

import com.flow.framework.base.properties.FrameworkBaseConfigProperties;
import com.flow.framework.base.properties.component.AllocationRemoteConfigProperties;
import com.flow.framework.common.health.ServiceHealthCheckCode;
import com.flow.framework.common.util.verify.VerifyUtil;
import com.flow.framework.core.system.checker.AbstractSystemStatusChecker;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 指定三方调用网络监控（基于TCP的监控）
 *
 * @author luoguopiao
 * @version 0.0.1
 * @date 2022/12/17
 */
@Slf4j
public class AllocationRemoteStatusChecker extends AbstractSystemStatusChecker {

    private FrameworkBaseConfigProperties frameworkBaseConfigProperties;

    public AllocationRemoteStatusChecker(FrameworkBaseConfigProperties frameworkBaseConfigProperties) {
        this.frameworkBaseConfigProperties = frameworkBaseConfigProperties;
    }

    /**
     * @inheritDoc
     */
    @Override
    public int getServiceHealthCheckCode() {
        return ServiceHealthCheckCode.SERVICE_OUTER_NET_CODE;
    }

    /**
     * @inheritDoc
     */
    @Override
    protected Set<String> executeAsyncHealthCheck() {
        List<AllocationRemoteConfigProperties.Remote> remotes = frameworkBaseConfigProperties.getAllocation().getRemotes();
        if (VerifyUtil.isEmpty(remotes)) {
            return Collections.emptySet();
        }
        Set<String> unhealthyTags = new HashSet<>();
        for (AllocationRemoteConfigProperties.Remote remote : remotes) {
            String host = remote.getHost();
            int port = remote.getPort();
            Socket socket = new Socket();
            try {
                socket.connect(new InetSocketAddress(host, port), 1000);
            } catch (Exception e) {
                log.error("check remote error, host: {}", host);
                unhealthyTags.add(host + ":" + port);
            } finally {
                try {
                    socket.close();
                } catch (IOException ignore) {

                }
            }
        }
        return unhealthyTags;
    }

    /**
     * @inheritDoc
     */
    @Override
    public long getInitialDelay() {
        return 0;
    }

    /**
     * @inheritDoc
     */
    @Override
    public long getPeriod() {
        return 30000;
    }
}
